// @flow

import * as React from 'react';
import { I18n } from '@lingui/react';
import { t, Trans } from '@lingui/macro';
import Grid from '@material-ui/core/Grid';
import GridList from '@material-ui/core/GridList';
import Divider from '@material-ui/core/Divider';
import Collapse from '@material-ui/core/Collapse';
import TeamContext from '../../../../../Profile/Team/TeamContext';
import Dialog, { DialogPrimaryButton } from '../../../../../UI/Dialog';
import Text from '../../../../../UI/Text';
import AuthenticatedUserContext from '../../../../../Profile/AuthenticatedUserContext';
import UserLine from '../../../../../UI/User/UserLine';
import FlatButton from '../../../../../UI/FlatButton';
import LeftLoader from '../../../../../UI/LeftLoader';
import Form from '../../../../../UI/Form';
import {
  ColumnStackLayout,
  LineStackLayout,
  ResponsiveLineStackLayout,
} from '../../../../../UI/Layout';
import TextField from '../../../../../UI/TextField';
import { emailRegex } from '../../../../../Utils/EmailUtils';
import RaisedButton from '../../../../../UI/RaisedButton';
import Add from '../../../../../UI/CustomSvgIcons/Add';
import { groupMembersByGroupId, sortGroupsWithMembers } from '../Utils';
import { Column, Line, Spacer } from '../../../../../UI/Grid';
import ManageStudentRow from './ManageStudentRow';
import AlertMessage from '../../../../../UI/AlertMessage';
import Link from '../../../../../UI/Link';
import TeamAvailableSeats from '../TeamAvailableSeats';
import { copyTextToClipboard } from '../../../../../Utils/Clipboard';
import ChevronArrowTop from '../../../../../UI/CustomSvgIcons/ChevronArrowTop';
import ChevronArrowBottom from '../../../../../UI/CustomSvgIcons/ChevronArrowBottom';
import Paper from '../../../../../UI/Paper';
import Checkbox from '../../../../../UI/Checkbox';
import CheckboxUnchecked from '../../../../../UI/CustomSvgIcons/CheckboxUnchecked';
import CheckboxChecked from '../../../../../UI/CustomSvgIcons/CheckboxChecked';
import Archive from '../../../../../UI/CustomSvgIcons/Archive';
import Recycle from '../../../../../UI/CustomSvgIcons/Recycle';
import IconButton from '../../../../../UI/IconButton';
import { extractGDevelopApiErrorStatusAndCode } from '../../../../../Utils/GDevelopServices/Errors';
import StudentCreationCard from '../StudentCreationCard';
import CircularProgress from '../../../../../UI/CircularProgress';
import { useResponsiveWindowSize } from '../../../../../UI/Responsive/ResponsiveWindowMeasurer';
import Copy from '../../../../../UI/CustomSvgIcons/Copy';
import Education from '../../../../../Profile/Subscription/Icons/Education';
import Window from '../../../../../Utils/Window';
import useAlertDialog from '../../../../../UI/Alert/useAlertDialog';
import { delay } from '../../../../../Utils/Delay';
import Check from '../../../../../UI/CustomSvgIcons/Check';
import useSubscriptionPlans from '../../../../../Utils/UseSubscriptionPlans';
import { getPlanIcon } from '../../../../../Profile/Subscription/PlanCard';
import { selectMessageByLocale } from '../../../../../Utils/i18n/MessageByLocale';
import TextButton from '../../../../../UI/TextButton';
import Chip from '../../../../../UI/Chip';
import { SubscriptionSuggestionContext } from '../../../../../Profile/Subscription/SubscriptionSuggestionContext';

const styles = {
  selectedMembersControlsContainer: {
    padding: 8,
  },
  selectedMembersControlsContainerMobile: {
    padding: 8,
    marginTop: 12,
    marginBottom: 12,
  },
  subscriptionPaper: {
    padding: '8px 16px 8px 8px',
  },
};

type AddTeacherError =
  | 'no-seats-available'
  | 'user-not-found'
  | 'user-already-added'
  | 'user-has-subscription'
  | 'user-with-autogenerated-email'
  | 'user-owner'
  | 'not-allowed'
  | 'unexpected';
type RemoveTeacherError =
  | 'user-not-found'
  | 'user-owner'
  | 'user-not-admin'
  | 'not-allowed'
  | 'unexpected';

const addErrorToText = {
  'no-seats-available': (
    <Trans>Your team does not have enough seats for a new admin.</Trans>
  ),
  'user-not-found': <Trans>The email you provided could not be found.</Trans>,
  'user-already-added': (
    <Trans>The email you provided is already an admin in your team.</Trans>
  ),
  'user-has-subscription': (
    <Trans>
      The email you provided already has a subscription with GDevelop. Please
      ask them to cancel it before defining them as teacher in your team.
    </Trans>
  ),
  'user-with-autogenerated-email': (
    <Trans>A student account cannot be an admin of your team.</Trans>
  ),
  'user-owner': (
    <Trans>The main account of the Education plan cannot be modified.</Trans>
  ),
  'not-allowed': (
    <Trans>You don't have enough rights to add a new admin.</Trans>
  ),
  unexpected: (
    <Trans>
      An unexpected error happened. Please contact us for more details.
    </Trans>
  ),
};

const removeErrorToText = {
  'user-not-found': <Trans>The email you provided could not be found.</Trans>,
  'user-not-admin': (
    <Trans>The email you provided is not an admin in your team.</Trans>
  ),
  'user-owner': (
    <Trans>The main account of the Education plan cannot be modified.</Trans>
  ),
  'not-allowed': (
    <Trans>You don't have enough rights to add a new admin.</Trans>
  ),
  unexpected: (
    <Trans>
      An unexpected error happened. Please contact us for more details.
    </Trans>
  ),
};

const purchaseSeatsMailToLink =
  'mailto:education@gdevelop.io?subject=Purchase%20Education%20plan%20seats';

type AddTeacherDialogProps = {|
  onClose: () => void,
  onAddTeacher: (email: string) => Promise<void>,
|};

const AddTeacherDialog = ({ onClose, onAddTeacher }: AddTeacherDialogProps) => {
  const [email, setEmail] = React.useState<string>('');
  const [actionInProgress, setActionInProgress] = React.useState(false);
  const [isEmailValid, setIsEmailValid] = React.useState<boolean>(true);
  const [addError, setAddError] = React.useState<?AddTeacherError>(null);

  const doAddTeacher = React.useCallback(
    async () => {
      setActionInProgress(true);
      setAddError(null);
      try {
        await onAddTeacher(email);
        setEmail('');
      } catch (error) {
        console.error(error);
        const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
          error
        );
        if (!extractedStatusAndCode) {
          setAddError('unexpected');
        } else {
          let error;
          if (extractedStatusAndCode.status === 404) {
            error = 'user-not-found';
          } else if (extractedStatusAndCode.status === 403) {
            error = 'not-allowed';
          } else if (
            extractedStatusAndCode.code ===
            'team-admin-creation/user-with-autogenerated-email'
          ) {
            error = 'user-with-autogenerated-email';
          } else if (
            extractedStatusAndCode.code ===
            'team-admin-creation/owner-cannot-be-modified'
          ) {
            error = 'user-owner';
          } else if (
            extractedStatusAndCode.code === 'team-admin-creation/team-full'
          ) {
            error = 'no-seats-available';
          } else if (
            extractedStatusAndCode.code ===
            'team-admin-creation/user-has-subscription'
          ) {
            error = 'user-has-subscription';
          } else if (
            extractedStatusAndCode.code === 'team-admin-creation/user-not-admin'
          ) {
            error = 'user-already-added';
          } else {
            error = 'unexpected';
          }
          setAddError(error);
        }
      } finally {
        setActionInProgress(false);
      }
    },
    [email, onAddTeacher]
  );

  return (
    <Dialog
      title={<Trans>Add a teacher</Trans>}
      actions={[
        <FlatButton
          label={<Trans>Back</Trans>}
          disabled={actionInProgress}
          key="back"
          primary={false}
          onClick={onClose}
        />,
        <LeftLoader isLoading={actionInProgress} key="add-collaborator">
          <DialogPrimaryButton
            label={<Trans>Add</Trans>}
            primary
            onClick={doAddTeacher}
            disabled={actionInProgress}
          />
        </LeftLoader>,
      ]}
      maxWidth="xs"
      cannotBeDismissed={actionInProgress}
      onRequestClose={onClose}
      onApply={doAddTeacher}
      open
    >
      <Form onSubmit={doAddTeacher} name="addCollaborator">
        <ColumnStackLayout noMargin>
          <TextField
            autoFocus="desktop"
            value={email}
            floatingLabelText={<Trans>Email</Trans>}
            type="email"
            onChange={(e, value) => {
              if (!isEmailValid) setIsEmailValid(true);
              if (addError) setAddError(null);
              setEmail(value);
            }}
            errorText={
              !isEmailValid ? <Trans>Invalid email address.</Trans> : null
            }
            fullWidth
            onBlur={event => {
              const trimmedEmail = event.currentTarget.value.trim();
              setEmail(trimmedEmail);
              if (trimmedEmail) {
                setIsEmailValid(emailRegex.test(trimmedEmail));
              }
            }}
            disabled={actionInProgress}
          />
          {addError && (
            <AlertMessage kind="error">{addErrorToText[addError]}</AlertMessage>
          )}
        </ColumnStackLayout>
      </Form>
    </Dialog>
  );
};

type Props = {|
  onClose: () => void,
|};

const ManageEducationAccountDialog = ({ onClose }: Props) => {
  const { profile, subscription } = React.useContext(AuthenticatedUserContext);
  const { openSubscriptionDialog } = React.useContext(
    SubscriptionSuggestionContext
  );
  const { subscriptionPlansWithPricingSystems } = useSubscriptionPlans({
    includeLegacy: true,
  });
  const [selectedUserIds, setSelectedUserIds] = React.useState<string[]>([]);
  const [isCreatingMembers, setIsCreatingMembers] = React.useState<boolean>(
    false
  );
  const [isArchivingAccounts, setIsArchivingAccounts] = React.useState<boolean>(
    false
  );
  const [isRestoringAccounts, setIsRestoringAccounts] = React.useState<boolean>(
    false
  );
  const [
    credentialsCopySuccess,
    setCredentialsCopySuccess,
  ] = React.useState<boolean>(false);
  const [
    adminEmailBeingRemoved,
    setAdminEmailBeingRemoved,
  ] = React.useState<?string>(null);
  const [
    removeAdminError,
    setRemoveAdminError,
  ] = React.useState<?RemoveTeacherError>(null);
  const { showConfirmation } = useAlertDialog();
  const { isMobile } = useResponsiveWindowSize();
  const [batchControlError, setBatchControlError] = React.useState<React.Node>(
    null
  );
  const [
    addTeacherDialogOpen,
    setAddTeacherDialogOpen,
  ] = React.useState<boolean>(false);
  const [
    isArchivedAccountsSectionOpen,
    setIsArchivedAccountsSectionOpen,
  ] = React.useState<boolean>(false);
  const {
    groups,
    team,
    admins,
    members,
    memberships,
    onRefreshMembers,
    getAvailableSeats,
    onCreateMembers,
    onChangeMemberPassword,
    onActivateMembers,
    onSetAdmin,
    onRefreshAdmins,
  } = React.useContext(TeamContext);

  React.useEffect(
    () => {
      (async () => {
        if (!credentialsCopySuccess) return;
        await delay(2000);
        setCredentialsCopySuccess(false);
      })();
    },
    [credentialsCopySuccess]
  );

  const onChangeTeamMemberPassword = React.useCallback(
    async ({
      userId,
      newPassword,
    }: {|
      userId: string,
      newPassword: string,
    |}) => {
      await onChangeMemberPassword(userId, newPassword);
      await onRefreshMembers();
    },
    [onRefreshMembers, onChangeMemberPassword]
  );

  const onCopyActiveCredentials = React.useCallback(
    () => {
      if (!members) return;
      let content = 'Username,Email,Password';
      let membersToConsider = [];
      if (selectedUserIds.length === 0) {
        membersToConsider = members.filter(member => !member.deactivatedAt);
      } else {
        membersToConsider = members.filter(member =>
          selectedUserIds.includes(member.id)
        );
      }
      membersToConsider.forEach(member => {
        content += `\n${member.username || ''},${
          member.email
        },${member.password || ''}`;
      });
      copyTextToClipboard(content);
      setCredentialsCopySuccess(true);
    },
    [selectedUserIds, members]
  );

  const isLoading = !subscriptionPlansWithPricingSystems;

  const availableSeats = getAvailableSeats();
  const userSubscriptionPlanWithPricingSystems =
    subscription && subscription.planId && subscriptionPlansWithPricingSystems
      ? subscriptionPlansWithPricingSystems.find(
          subscriptionPlanWithPricingSystems =>
            subscriptionPlanWithPricingSystems.id === subscription.planId
        )
      : null;

  const onCreateTeamMembers = React.useCallback(
    async (quantity: number) => {
      if (!availableSeats || quantity > availableSeats || isCreatingMembers) {
        return;
      }
      setIsCreatingMembers(true);
      try {
        await onCreateMembers(quantity);
        await onRefreshMembers();
      } catch (error) {
        console.error(`An error occurred when creating members: `, error);
      } finally {
        setIsCreatingMembers(false);
      }
    },
    [onCreateMembers, onRefreshMembers, availableSeats, isCreatingMembers]
  );

  const onRemoveAdmin = React.useCallback(
    async (email: string) => {
      setAdminEmailBeingRemoved(email);
      setRemoveAdminError(null);
      try {
        await onSetAdmin(email, false);
        await onRefreshAdmins();
      } catch (error) {
        console.error(error);
        const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
          error
        );
        if (!extractedStatusAndCode) {
          setRemoveAdminError('unexpected');
        } else {
          let error;
          if (extractedStatusAndCode.status === 404) {
            error = 'user-not-found';
          } else if (extractedStatusAndCode.status === 403) {
            error = 'not-allowed';
          } else if (
            extractedStatusAndCode.code ===
            'team-admin-creation/owner-cannot-be-modified'
          ) {
            error = 'user-owner';
          } else if (
            extractedStatusAndCode.code === 'team-admin-creation/user-not-admin'
          ) {
            error = 'user-not-admin';
          } else {
            error = 'unexpected';
          }
          setRemoveAdminError(error);
        }
      } finally {
        setAdminEmailBeingRemoved(null);
      }
    },
    [onSetAdmin, onRefreshAdmins]
  );

  const onSetUserAsAdmin = React.useCallback(
    async (email: string) => {
      await onSetAdmin(email, true);
      await onRefreshAdmins();
    },
    [onSetAdmin, onRefreshAdmins]
  );

  const onActivateTeamMembers = React.useCallback(
    async (activate: boolean) => {
      if (selectedUserIds.length === 0) return;
      setBatchControlError(null);

      try {
        if (!activate) {
          const confirm = await showConfirmation({
            title: t`Archive ${selectedUserIds.length} accounts?`,
            confirmButtonLabel: t`Archive ${selectedUserIds.length} accounts`,
            dismissButtonLabel: t`Cancel`,
            message: t`Projects in disabled accounts will not be deleted. All disabled accounts can be reactivated after 15 days.`,
            level: 'info',
            maxWidth: 'xs',
          });
          if (!confirm) return;
        }
        if (activate) {
          setIsRestoringAccounts(true);
        } else {
          setIsArchivingAccounts(true);
        }
        await onActivateMembers(selectedUserIds, activate);
        if (!activate) {
          // If accounts are archived, they might disappear under the collapsed section
          // "Archived accounts" so we unselect them to avoid any mistake around user selection.
          setSelectedUserIds([]);
        }
        await onRefreshMembers();
      } catch (error) {
        const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
          error
        );
        let errorMessage: React.Node = null;
        if (extractedStatusAndCode) {
          if (extractedStatusAndCode.code === 'user-activation/team-full') {
            errorMessage = (
              <Trans>
                You don't have enough available seats to restore those accounts.
              </Trans>
            );
          } else if (
            extractedStatusAndCode.code ===
            'user-activation/user-deactivated-recently'
          ) {
            errorMessage = (
              <Trans>
                You have to wait
                {extractedStatusAndCode.data
                  ? extractedStatusAndCode.data.daysToWait
                  : 15}
                days before you can reactivate an archived account.
              </Trans>
            );
          } else if (
            extractedStatusAndCode.code ===
            'user-activation/member-outside-of-team'
          ) {
            errorMessage = (
              <Trans>
                You don't have enough rights to manage those accounts.
              </Trans>
            );
          }
        }
        if (!errorMessage) {
          errorMessage = (
            <>
              <Trans>An unknown error happened.</Trans>{' '}
              <Trans>
                Please check your internet connection or try again later.
              </Trans>
            </>
          );
        }
        setBatchControlError(errorMessage);
      } finally {
        if (activate) {
          setIsRestoringAccounts(false);
        } else {
          setIsArchivingAccounts(false);
        }
      }
    },
    [onActivateMembers, onRefreshMembers, selectedUserIds, showConfirmation]
  );

  const groupedMembers = groupMembersByGroupId({
    groups,
    members,
    memberships,
  });

  if (
    !admins ||
    !members ||
    !team ||
    !groups ||
    !memberships ||
    !groupedMembers
  ) {
    return null;
  }
  const {
    active: membersByGroupId,
    inactive: archivedMembers,
  } = groupedMembers;
  const groupsWithMembers = [
    membersByGroupId['NONE']
      ? { group: null, members: membersByGroupId['NONE'].members }
      : null,
    ...sortGroupsWithMembers(membersByGroupId),
  ].filter(Boolean);

  const activeMembers = members.filter(member => !member.deactivatedAt);
  const areAllActiveMembersSelected = activeMembers.every(member =>
    selectedUserIds.includes(member.id)
  );
  const selectedMembers = members.filter(member =>
    selectedUserIds.includes(member.id)
  );
  const isAtLeastOneSelectedUserActive = selectedMembers.some(
    member => !member.deactivatedAt
  );
  const isAtLeastOneSelectedUserArchived = selectedMembers.some(
    member => !!member.deactivatedAt
  );
  const hasNoTeamMembers = members.length === 0;
  const hasNoActiveTeamMembers = activeMembers.length === 0;

  return (
    <I18n>
      {({ i18n }) => (
        <>
          <Dialog
            title={<Trans>Manage seats</Trans>}
            flexColumnBody
            fullHeight
            open
            onRequestClose={onClose}
          >
            {isLoading ? (
              <Column
                useFullHeight
                expand
                justifyContent="center"
                alignItems="center"
              >
                <CircularProgress />
              </Column>
            ) : (
              <ColumnStackLayout noMargin>
                {userSubscriptionPlanWithPricingSystems && (
                  <Paper background="light" style={styles.subscriptionPaper}>
                    <ResponsiveLineStackLayout
                      alignItems="center"
                      justifyContent="space-between"
                      noMargin
                    >
                      <LineStackLayout noMargin alignItems="center">
                        {getPlanIcon({
                          subscriptionPlan: userSubscriptionPlanWithPricingSystems,
                          logoSize: 20,
                        })}
                        <Text noMargin>
                          <b>
                            {selectMessageByLocale(
                              i18n,
                              userSubscriptionPlanWithPricingSystems.nameByLocale
                            ).toUpperCase()}
                          </b>
                        </Text>
                        <Chip label={team.seats} size="small" />
                        <Text noMargin color="secondary">
                          <Trans>Seats</Trans>
                        </Text>
                      </LineStackLayout>
                      <TextButton
                        secondary
                        label={<Trans>Manage subscription</Trans>}
                        onClick={() =>
                          openSubscriptionDialog({
                            analyticsMetadata: {
                              reason: 'Manage subscription as teacher',
                            },
                            filter: 'education',
                          })
                        }
                      />
                    </ResponsiveLineStackLayout>
                  </Paper>
                )}
                {availableSeats === 0 && (
                  <AlertMessage kind="info">
                    <Trans>
                      You’ve reached the maximum amount of available seats.{' '}
                      <Link
                        href={purchaseSeatsMailToLink}
                        onClick={() =>
                          Window.openExternalURL(purchaseSeatsMailToLink)
                        }
                      >
                        Increase the number of seats
                      </Link>{' '}
                      on your subscription to invite more students and
                      collaborators.
                    </Trans>
                  </AlertMessage>
                )}
                <Text size="sub-title" noMargin>
                  <Trans>Teacher accounts</Trans>
                </Text>
                <Column noMargin>
                  {admins &&
                    admins.map(adminUser => (
                      <UserLine
                        key={adminUser.id}
                        username={adminUser.username}
                        email={adminUser.email}
                        level={null}
                        onDelete={() => onRemoveAdmin(adminUser.email)}
                        disabled={
                          (profile && adminUser.id === profile.id) ||
                          (adminEmailBeingRemoved &&
                            adminEmailBeingRemoved === adminUser.email)
                        }
                      />
                    ))}
                </Column>
                {removeAdminError && (
                  <AlertMessage kind="error">
                    {removeErrorToText[removeAdminError]}
                  </AlertMessage>
                )}
                <Line noMargin>
                  <RaisedButton
                    primary
                    disabled={availableSeats !== null && availableSeats <= 0}
                    icon={<Add fontSize="small" />}
                    label={<Trans>Add teacher</Trans>}
                    onClick={() => setAddTeacherDialogOpen(true)}
                  />
                </Line>
                <Divider />
                <ResponsiveLineStackLayout
                  noMargin
                  justifyContent="space-between"
                  alignItems="center"
                >
                  <Text size="sub-title" noMargin>
                    <Trans>Student accounts</Trans>
                  </Text>
                  <LineStackLayout noMargin alignItems="center">
                    <TeamAvailableSeats />
                    <Line expand noMargin justifyContent="flex-end">
                      {availableSeats !== null && availableSeats <= 0 ? (
                        <FlatButton
                          primary
                          label={<Trans>Purchase seats</Trans>}
                          leftIcon={<Education fontSize="small" />}
                          onClick={() =>
                            Window.openExternalURL(purchaseSeatsMailToLink)
                          }
                        />
                      ) : (
                        <RaisedButton
                          primary
                          label={<Trans>Add student</Trans>}
                          icon={
                            isCreatingMembers ? (
                              <CircularProgress size={10} />
                            ) : (
                              <Add fontSize="small" />
                            )
                          }
                          onClick={() => onCreateTeamMembers(1)}
                          disabled={isCreatingMembers}
                        />
                      )}
                    </Line>
                  </LineStackLayout>
                </ResponsiveLineStackLayout>
                {hasNoTeamMembers && availableSeats !== null && (
                  <StudentCreationCard
                    availableSeats={availableSeats}
                    isCreatingMembers={isCreatingMembers}
                    onCreateStudentAccounts={onCreateTeamMembers}
                  />
                )}
                {(!hasNoTeamMembers || !hasNoActiveTeamMembers) && (
                  <ColumnStackLayout noMargin>
                    <Paper
                      style={
                        isMobile
                          ? styles.selectedMembersControlsContainerMobile
                          : styles.selectedMembersControlsContainer
                      }
                      background="light"
                    >
                      <ColumnStackLayout noMargin>
                        <Line
                          justifyContent="space-between"
                          noMargin
                          alignItems="center"
                        >
                          <LineStackLayout alignItems="center" noMargin>
                            <Checkbox
                              style={{ margin: 0 }}
                              checked={
                                areAllActiveMembersSelected &&
                                selectedUserIds.length > 0
                              }
                              onCheck={(e, checked) => {
                                if (checked) {
                                  setSelectedUserIds(
                                    members
                                      .filter(member => !member.deactivatedAt)
                                      .map(member => member.id)
                                  );
                                } else {
                                  setSelectedUserIds([]);
                                }
                              }}
                              uncheckedIcon={<CheckboxUnchecked />}
                              checkedIcon={<CheckboxChecked />}
                            />
                            <Text noMargin>
                              <Trans>Select all active</Trans>
                            </Text>
                          </LineStackLayout>
                          <LineStackLayout noMargin alignItems="center">
                            <IconButton
                              size="small"
                              tooltip={t`Archive accounts`}
                              disabled={
                                selectedUserIds.length === 0 ||
                                isAtLeastOneSelectedUserArchived ||
                                isArchivingAccounts
                              }
                              onClick={() => onActivateTeamMembers(false)}
                            >
                              {isArchivingAccounts ? (
                                <CircularProgress size={22} />
                              ) : (
                                <Archive />
                              )}
                            </IconButton>
                            <IconButton
                              size="small"
                              tooltip={t`Restore accounts`}
                              disabled={
                                selectedUserIds.length === 0 ||
                                isAtLeastOneSelectedUserActive ||
                                isRestoringAccounts
                              }
                              onClick={() => onActivateTeamMembers(true)}
                            >
                              {isRestoringAccounts ? (
                                <CircularProgress size={22} />
                              ) : (
                                <Recycle />
                              )}
                            </IconButton>
                            <IconButton
                              size="small"
                              tooltip={
                                selectedUserIds.length === 0
                                  ? t`Copy active credentials`
                                  : t`Copy ${
                                      selectedUserIds.length
                                    } credentials`
                              }
                              disabled={
                                hasNoActiveTeamMembers &&
                                selectedUserIds.length === 0
                              }
                              onClick={onCopyActiveCredentials}
                            >
                              {credentialsCopySuccess ? <Check /> : <Copy />}
                            </IconButton>
                          </LineStackLayout>
                        </Line>
                        {batchControlError && (
                          <AlertMessage kind="error">
                            {batchControlError}
                          </AlertMessage>
                        )}
                      </ColumnStackLayout>
                    </Paper>
                    <Column>
                      {!isMobile && (
                        <GridList cols={2} cellHeight={'auto'}>
                          <Grid item xs={5}>
                            <Text style={{ opacity: 0.7 }}>
                              <Trans>Student</Trans>
                            </Text>
                          </Grid>
                          <Grid item xs={7}>
                            <Text style={{ opacity: 0.7 }}>
                              <Trans>Password</Trans>
                            </Text>
                          </Grid>
                        </GridList>
                      )}
                      {groupsWithMembers.map(({ group, members }, index) => {
                        return (
                          <React.Fragment key={group ? group.id : 'lobby'}>
                            {index > 0 && <Spacer />}
                            <Line noMargin>
                              <Text size="sub-title">
                                {group ? (
                                  <Trans>Room: {group.name}</Trans>
                                ) : (
                                  <Trans>Lobby</Trans>
                                )}
                              </Text>
                            </Line>
                            <Column>
                              <GridList
                                cols={isMobile ? 3 : 2}
                                cellHeight={'auto'}
                              >
                                {members.map(member => {
                                  return (
                                    <ManageStudentRow
                                      member={member}
                                      key={member.id}
                                      onChangePassword={
                                        onChangeTeamMemberPassword
                                      }
                                      isSelected={selectedUserIds.includes(
                                        member.id
                                      )}
                                      onSelect={selected => {
                                        const memberIndexInArray = selectedUserIds.indexOf(
                                          member.id
                                        );
                                        if (selected) {
                                          if (memberIndexInArray === -1) {
                                            setSelectedUserIds([
                                              ...selectedUserIds,
                                              member.id,
                                            ]);
                                          }
                                          return;
                                        } else {
                                          const newArray = [...selectedUserIds];
                                          if (memberIndexInArray >= 0) {
                                            newArray.splice(
                                              memberIndexInArray,
                                              1
                                            );
                                            setSelectedUserIds(newArray);
                                          }
                                        }
                                      }}
                                    />
                                  );
                                })}
                              </GridList>
                            </Column>
                          </React.Fragment>
                        );
                      })}
                      {archivedMembers.length > 0 && (
                        <React.Fragment key={'archived'}>
                          <Spacer />
                          <Line noMargin>
                            {isArchivedAccountsSectionOpen ? (
                              <IconButton
                                size="small"
                                edge="end"
                                aria-label="collapse"
                                onClick={() =>
                                  setIsArchivedAccountsSectionOpen(false)
                                }
                              >
                                <ChevronArrowTop />
                              </IconButton>
                            ) : (
                              <IconButton
                                size="small"
                                edge="end"
                                aria-label="expand"
                                onClick={() =>
                                  setIsArchivedAccountsSectionOpen(true)
                                }
                              >
                                <ChevronArrowBottom />
                              </IconButton>
                            )}
                            <Text size="sub-title">
                              <Trans>Archived accounts</Trans>
                            </Text>
                          </Line>
                          <Column>
                            <Collapse
                              in={isArchivedAccountsSectionOpen}
                              timeout="auto"
                              unmountOnExit
                            >
                              <GridList cols={2} cellHeight={'auto'}>
                                {archivedMembers.map(member => {
                                  return (
                                    <ManageStudentRow
                                      member={member}
                                      key={member.id}
                                      isArchived
                                      onChangePassword={
                                        onChangeTeamMemberPassword
                                      }
                                      isSelected={selectedUserIds.includes(
                                        member.id
                                      )}
                                      onSelect={selected => {
                                        const memberIndexInArray = selectedUserIds.indexOf(
                                          member.id
                                        );
                                        if (selected) {
                                          if (memberIndexInArray === -1) {
                                            setSelectedUserIds([
                                              ...selectedUserIds,
                                              member.id,
                                            ]);
                                          }
                                          return;
                                        } else {
                                          const newArray = [...selectedUserIds];
                                          if (memberIndexInArray >= 0) {
                                            newArray.splice(
                                              memberIndexInArray,
                                              1
                                            );
                                            setSelectedUserIds(newArray);
                                          }
                                        }
                                      }}
                                    />
                                  );
                                })}
                              </GridList>
                            </Collapse>
                          </Column>
                        </React.Fragment>
                      )}
                    </Column>
                  </ColumnStackLayout>
                )}
              </ColumnStackLayout>
            )}
          </Dialog>
          {addTeacherDialogOpen && (
            <AddTeacherDialog
              onClose={() => setAddTeacherDialogOpen(false)}
              onAddTeacher={onSetUserAsAdmin}
            />
          )}
        </>
      )}
    </I18n>
  );
};

export default ManageEducationAccountDialog;
